package term.dept.course.section;

import java.util.ArrayList;

import book.Book;

import term.dept.Department;
import term.dept.course.Course;

import Util.Util;
import adoption.Adoption;

import exception.InvalidAdoptionException;
import exception.InvalidBookException;
import exception.InvalidNameException;
import exception.InvalidStatusException;

/**
 * Represents an individual section of a course within a department.
 * Contains instructor, enrollment, and adoption information.
 * @author SJP
 *
 */
public class Section {
	
	/**
	 * The department of this section
	 */
	private Department d;
	
	/**
	 * The course of this section
	 */
	private Course c;
	
	/**
	 * String identifying this section
	 */
	private String id;
	
	/**
	 * Instructor for ths section
	 */
	private Instructor inst;
	
	/**
	 * Enrollment values for this section
	 */
	private Enrollment enrollment;
	
	/**
	 * Book adoptions for this section
	 */
	private ArrayList<Adoption> adoptions;
	
	private int sec_id;
	private boolean changed = false;
	private static int next_id = 0;
	
	/**
	 * Create a new section
	 * @param nd department
	 * @param nc course
	 * @param nid id
	 * @param ninst instructor
	 */
	public Section(Department nd, Course nc, String nid, Instructor ninst) {
		this(nd,nc,nid,ninst,next_id++);
		changed();
	}
	
	public Section(Department nd, Course nc, String nid, Instructor ninst, int s_id) {
		d = nd;
		c = nc;
		id = nid;
		inst = ninst;
		sec_id = s_id;
		enrollment = new Enrollment();
		adoptions = new ArrayList<Adoption>();
		
		//System.out.println(d.getCode().toString()+" "+c.toString()+" "+toString()+" sec_id: "+s_id);
	}
	
	/**
	 * @return the sec_id
	 */
	public int getSec_id() {
		return sec_id;
	}

	/**
	 * @return the department of this section
	 */
	public Department getDept() {return d;}
	
	/**
	 * @return the course of this section
	 */
	public Course getCourse() {return c;}
	
	/**
	 * @return id
	 */
	public String getID() {return id;}
	
	/**
	 * @return instructor
	 */
	public Instructor getInst() {return inst;}
	
	/**
	 * @return all of the adoptions for this section
	 */
	public ArrayList<Adoption> getAdoptions() {return adoptions;}
	
	/**
	 * Add a new adoption for this section
	 * @param b the book to adopt
	 * @param status req/opt/alt/pc
	 * @return the new adoption
	 */
	public Adoption addAdoption(Book b, String status) throws InvalidBookException, InvalidStatusException, InvalidAdoptionException{
		
		if (adoptions.contains(b))
			throw new InvalidBookException("Section: addAdoption: Book \""+b.toString()+"\"");
		else {
			Adoption a = new Adoption(this,b,status);
			adoptions.add(a);
			changed();
			return a;
		}
	}
	
	/**
	 * Add an existing adoption to this section
	 * @param b the book to adopt
	 * @param status req/opt/alt/pc
	 * @return the new adoption
	 */
	public boolean addAdoption(Adoption a){
		for (Adoption ad : adoptions)
			if (ad.contains(a.getBook()))
				return false;
		//setChanged(false);
		return adoptions.add(a);
	}
	
	/**
	 * @return the enrollments for this section
	 */
	public Enrollment getEnrollment() {return enrollment;}
	
	public void setEnrollments(int prev, int est, int cur, int max) {
		enrollment.setPrev(prev);
		enrollment.setEst(est);
		enrollment.setCur(cur);
		enrollment.setCap(max);
	}
	
	/**
	 * Record the previous enrollment for this section
	 * @param prev
	 * @return the prev enrollment
	 */
	public int setPrevEnroll(int prev) {changed();return enrollment.setPrev(prev);}
	
	/**
	 * Record the estimated enrollment for this section
	 * @param est
	 * @return the est enrollment
	 */
	public int setEstEnroll(int est) {changed();return enrollment.setEst(est);}
	
	/**
	 * Record the current enrollment for this section
	 * @param cur
	 * @return the cur enrollment
	 */
	public int setCurEnroll(int cur) {changed();return enrollment.setCur(cur);}
	
	/**
	 * Record the maximum enrollment for this section
	 * @param max
	 * @return the max enrollment
	 */
	public int setMaxEnroll(int max) {changed();return enrollment.setCap(max);}
	
	/**
	 * TODO
	 */
	public void termRollover() {}
	
	public String toString() {return getID();}
	
	public String getFullName() {return d.getCode().getCode()+c.getNumber()+" "+id;}
	
	private void setChanged(boolean b) {changed = b;}
	
	private void changed() {
		Util.printStatusString(toString()+" changed()");
		setChanged(true);
	}
	
	public boolean isChanged() {return changed;}

	/**
	 * @param next_id the next_id to set
	 */
	public static void setNext_id(int next_id) {
		Section.next_id = next_id;
	}
}
